﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using AdventureWorks.Entities;

namespace AdventureWorksTests.Fakes
{
	public class FakeDbSet<T> : IDbSet<T> where T : Entity
	{
		private readonly HashSet<T> _set;

		public FakeDbSet()
		{
			_set = new HashSet<T>();
		}


		public T Update(T entity)
		{
			T oldEntity = Find(entity.ID);
			Remove(oldEntity);
			Add(entity);
			return entity;
		}

		public T Find(int id)
		{
			return _set.Single(i => i.ID == id);
		}

		public T Add(T entity)
		{
			_set.Add(entity);
			return entity;
		}

		public T Remove(T entity)
		{
			_set.Remove(entity);
			return entity;
		}


		public T Attach(T entity)
		{
			throw new NotImplementedException();
		}

		public T Find(params object[] keyValues)
		{
			throw new NotImplementedException();
		}

		public T Create()
		{
			throw new NotImplementedException();
		}

		public TDerivedEntity Create<TDerivedEntity>() where TDerivedEntity : class, T
		{
			return Activator.CreateInstance<TDerivedEntity>();
		}

		public ObservableCollection<T> Local
		{
			get
			{
				return new ObservableCollection<T>(_set);
			}
		}

		public IEnumerator<T> GetEnumerator()
		{
			return _set.GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}

		public IQueryProvider Provider
		{
			get { return _set.AsQueryable().Provider; }
		}

		public Expression Expression
		{
			get { return _set.AsQueryable().Expression; }
		}

		public Type ElementType
		{
			get { return _set.AsQueryable().ElementType; }
		}
	}
}
